var media = null
var dataCb = null
const WebRecord = function (stream) {
  media = stream
  let config = {}
  config.sampleBits = config.smapleBits || 16
  // config.sampleBits = config.smapleBits || 8
  config.sampleRate = config.sampleRate || 8000
  var audioCtx = new AudioContext()
  var mediaSrc = audioCtx.createMediaStreamSource(stream)
  var processor = audioCtx.createScriptProcessor(1024, 1, 1)
  var audioPkgLenth = 0
  var audioDataArr = []
  var recSampleRate = audioCtx.sampleRate
  var recSampleBits = 16
  var mySampleRate = config.sampleRate
  var mySampleBits = config.sampleBits
  processor.onaudioprocess = function (data) {
    if (dataCb !== null) {
      audioDataCom(data.inputBuffer.getChannelData(0))
    }
  }

  function clearIn() {
    audioDataArr = []
    audioPkgLenth = 0
  }

  function audioDataCom(data) {
    audioDataArr.push(new Float32Array(data))
    audioPkgLenth += data.length
    if (audioDataArr.length === 4) {
      if (dataCb) {
        dataCb(getData())
      }
      clearIn()
    }
  }

  function contactAudioArr() {
    var tmp = new Float32Array(audioPkgLenth)
    var v = 0
    for (var s = 0; s < audioDataArr.length; s++) {
      tmp.set(audioDataArr[s], v)
      v += audioDataArr[s].length
    }
    var p = parseInt(recSampleRate / mySampleRate)
    var tmpLen = tmp.length / p
    var out = new Float32Array(tmpLen)
    var r = 0,
      q = 0
    while (r < tmpLen) {
      out[r] = tmp[q]
      q += p
      r++
    }
    return out
  }

  // function getData() {//to wav
  //     var rate = Math.min(recSampleRate, mySampleRate)
  //     var bits = Math.min(recSampleBits, mySampleBits)
  //     var audioData = contactAudioArr()
  //     var p = audioData.length * (bits / 8)
  //     var tmp = new ArrayBuffer(44 + p)
  //     var result = new DataView(tmp)
  //     var r = 1
  //     var tmpLen = 0
  //     var xFunc = function (B) {
  //         for (var s = 0; s < B.length; s++) {
  //             result.setUint8(tmpLen + s, B.charCodeAt(s))
  //         }
  //     }
  //     xFunc('RIFF')
  //     tmpLen += 4
  //     result.setUint32(tmpLen, 36 + p, true)
  //     tmpLen += 4
  //     xFunc('WAVE')
  //     tmpLen += 4
  //     xFunc('fmt ')
  //     tmpLen += 4
  //     result.setUint32(tmpLen, 16, true)
  //     tmpLen += 4
  //     result.setUint16(tmpLen, 1, true)
  //     tmpLen += 2
  //     result.setUint16(tmpLen, r, true)
  //     tmpLen += 2
  //     result.setUint32(tmpLen, rate, true)
  //     tmpLen += 4
  //     result.setUint32(tmpLen, r * rate * (bits / 8), true)
  //     tmpLen += 4
  //     result.setUint16(tmpLen, r * (bits / 8), true)
  //     tmpLen += 2
  //     result.setUint16(tmpLen, bits, true)
  //     tmpLen += 2
  //     xFunc('data')
  //     tmpLen += 4
  //     result.setUint32(tmpLen, p, true)
  //     tmpLen += 4
  //     if (bits === 8) {
  //         for (var v = 0; v < audioData.length; v++, tmpLen++) {
  //             var z = Math.max(-1, Math.min(1, audioData[v]))
  //             var q = z < 0 ? z * 32768 : z * 32767
  //             q = parseInt(255 / (65535 / (q + 32768)))
  //             result.setInt8(tmpLen, q, true)
  //         }
  //     } else {
  //         for (var vv = 0; vv < audioData.length; vv++, tmpLen += 2) {
  //             var zz = Math.max(-1, Math.min(1, audioData[vv]))
  //             result.setInt16(tmpLen, zz < 0 ? zz * 32768 : zz * 32767, true)
  //         }
  //     }
  //
  //     return new Blob([result], {type: 'audio/wav'})
  // }
  function getData() {
    // pcm
    var bits = Math.min(recSampleBits, mySampleBits)
    var audioData = contactAudioArr()
    var p = audioData.length * (bits / 8)
    var tmp = new ArrayBuffer(p)
    var result = new DataView(tmp)
    var tmpLen = 0
    if (bits === 8) {
      for (var v = 0; v < audioData.length; v++, tmpLen++) {
        var z = Math.max(-1, Math.min(1, audioData[v]))
        var q = z < 0 ? z * 32768 : z * 32767
        q = parseInt(255 / (65535 / (q + 32768)))
        result.setInt8(tmpLen, q, true)
      }
    } else {
      for (var vv = 0; vv < audioData.length; vv++, tmpLen += 2) {
        var zz = Math.max(-1, Math.min(1, audioData[vv]))
        result.setInt16(tmpLen, zz < 0 ? zz * 32768 : zz * 32767, true)
      }
    }
    return result.buffer
  }

  this.start = function (cb) {
    dataCb = cb
    mediaSrc.connect(processor)
    processor.connect(audioCtx.destination)
  }
  this.stop = function () {
    processor.disconnect()
    let audioTracks = media.getAudioTracks()
    if (audioTracks.length > 0) {
      for (let i = 0; i < audioTracks.length; i++) {
        //停止播放轨道对应的源，源与轨道将脱离关联，同时轨道状态将设为“ended”。
        audioTracks[i].stop()
        //删除作为参数给出的 MediaStreamTrack
        media.removeTrack(audioTracks[i])
      }
    }
    dataCb = null
  }
  this.getBlob = function () {
    return getData()
  }
  this.clear = function () {
    clearIn()
  }
}
// let getMedia = (cb) => {
//   navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia
//   if (!navigator.getUserMedia) {
//     // alert('系统未检测到录音设备,请接入')
//     console.log('系统未检测到录音设备,请接入')
//     // cb(null)
//     // return
//   }
//   if (cb) {
//     console.log('cb', navigator.getUserMedia)
//     if (navigator.getUserMedia) {
//       navigator.getUserMedia(
//         { audio: true },
//         (med) => {
//           console.log('getUserMedia', med)
//           var rec = new WebRecord(med)
//           cb(rec)
//         },
//         () => {
//           console.log('other')
//         }
//       )
//     } else {
//       cb(null)
//     }
//   }
// }
let getMedia = (cb) => {
  if (cb) {
    console.log('cb', navigator.mediaDevices.getUserMedia)
    if (navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices
        .getUserMedia({ audio: true })
        .then((med) => {
          console.log('getUserMedia', med)
          var rec = new WebRecord(med)
          cb(rec)
        })
        .catch((e) => {
          console.log('other', e)
        })
    } else {
      cb(null)
    }
  }
}

const createRecord = (stream) => {
  return new WebRecord(stream)
}

export default {
  getMedia,
  createRecord
}
